package com.mall.user.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mall.common.util.JsonResult;
import com.mall.model.vo.UserStatsVO;
import com.mall.user.common.DeleteRequest;
import com.mall.user.common.exception.BusinessException;
import com.mall.user.common.response.ResultCode;
import com.mall.user.constant.UserConstant;
import com.mall.user.model.dto.user.*;
import com.mall.user.model.entity.User;
import com.mall.user.model.vo.LoginUserVO;
import com.mall.user.model.vo.UserVO;
import com.mall.user.service.UserService;
import com.mall.user.utils.ThrowUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.math.BigDecimal;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @Resource
    private PasswordEncoder passwordEncoder;

    /**
     * 检查用户是否有权限操作
     */
    private void checkAddressPermission(User currentUser, Long targetUserId) {
        if (currentUser == null) {
            throw new BusinessException(ResultCode.UNAUTHORIZED, "用户未登录");
        }

        // 如果是管理员，允许操作任何用户的地址
        if (UserConstant.ADMIN_ROLE.equals(currentUser.getUser_type())) {
            return;
        }

        // 如果不是管理员，只能操作自己的地址
        if (!currentUser.getId().equals(targetUserId)) {
            throw new BusinessException(ResultCode.FORBIDDEN, "无权限操作他人地址");
        }
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public JsonResult<LoginUserVO> userLogin(@Valid @RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        String userAccount = userLoginRequest.getAccount();
        String userPassword = userLoginRequest.getPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        LoginUserVO loginUserVO = userService.userLogin(userAccount, userPassword, request);
        return JsonResult.success(loginUserVO);
    }

    /**
     * 用户注销
     */
    @PostMapping("/logout")
    public JsonResult<Boolean> userLogout(HttpServletRequest request) {
        if (request == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        boolean result = userService.userLogout(request);
        return JsonResult.success(result);
    }

    /**
     * 获取当前登录用户
     */
    @GetMapping("/get/login")
    public JsonResult<LoginUserVO> getLoginUser(HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        return JsonResult.success(userService.getLoginUserVO(user));
    }

    /**
     * 根据ID获取用户信息
     */
    @GetMapping("/get/{id}")
    public JsonResult<UserVO> getUserById(@PathVariable("id") Long id) {
        if (id == null || id <= 0) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "用户ID不合法");
        }
        
        User user = userService.getById(id);
        if (user == null) {
            throw new BusinessException(ResultCode.NOT_FOUND, "用户不存在");
        }
        
        UserVO userVO = userService.getUserVO(user);
        return JsonResult.success(userVO);
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public JsonResult<Long> userRegister(@Valid @RequestBody UserRegisterRequest userRegisterRequest) {
        if (userRegisterRequest == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        String userName = userRegisterRequest.getUsername();
        String userPassword = userRegisterRequest.getPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        if (!userPassword.equals(checkPassword)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "两次输入的密码不一样");
        }
        long result = userService.userRegister(userName, userPassword, checkPassword);
        return JsonResult.success(result);
    }

    /**
     * 删除用户
     */
    @PostMapping("/delete")
    public JsonResult<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        boolean b = userService.removeById(deleteRequest.getId());
        return JsonResult.success(b);
    }

    /**
     * 更新用户
     */
    @PostMapping("/update")
    public JsonResult<Boolean> updateUser(@Valid @RequestBody UserUpdateRequest userUpdateRequest) {
        if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        User user = new User();
        BeanUtils.copyProperties(userUpdateRequest, user);
        boolean result = userService.updateById(user);
        ThrowUtils.throwIf(!result, ResultCode.FAILED);
        return JsonResult.success(true);
    }

    /**
     * 分页获取用户列表
     */
    @PostMapping("/list/page")
    public JsonResult<Page<User>> listUserByPage(@RequestBody UserQueryRequest userQueryRequest) {
        long current = userQueryRequest.getCurrent();
        long size = userQueryRequest.getPageSize();
        Page<User> userPage = userService.page(new Page<>(current, size),
                userService.getQueryWrapper(userQueryRequest));
        return JsonResult.success(userPage);
    }

    /**
     * 分页获取用户封装列表
     */
    @PostMapping("/list/page/vo")
    public JsonResult<Page<UserVO>> listUserVOByPage(@RequestBody UserQueryRequest userQueryRequest) {
        if (userQueryRequest == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        long current = userQueryRequest.getCurrent();
        long size = userQueryRequest.getPageSize();
        Page<User> userPage = userService.page(new Page<>(current, size),
                userService.getQueryWrapper(userQueryRequest));

        Page<UserVO> userVOPage = new Page<>(current, size, userPage.getTotal());
        List<UserVO> userVO = userService.getUserVO(userPage.getRecords());
        userVOPage.setRecords(userVO);
        return JsonResult.success(userVOPage);
    }

    /**
     * 更新个人信息
     */
    @PostMapping("/update/my")
    public JsonResult<Boolean> updateMyUser(@Valid @RequestBody UserUpdateMyRequest userUpdateMyRequest,
                                              HttpServletRequest request) {
        if (userUpdateMyRequest == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);
        // 只有本人或管理员才能操作
        checkAddressPermission(loginUser, loginUser.getId());

        User user = new User();
        BeanUtils.copyProperties(userUpdateMyRequest, user);
        user.setId(loginUser.getId());
        boolean result = userService.updateById(user);
        ThrowUtils.throwIf(!result, ResultCode.FAILED);
        return JsonResult.success(true);
    }


    /**
     * 更新个人信息
     */
    @PostMapping("/update/password")
    public JsonResult<Boolean> updateMyPassword(@Valid @RequestBody UserPasswordUpdateRequest req,
                                                  HttpServletRequest request) {
        if (req == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR);
        }

        User loginUser = userService.getLoginUser(request);
        // 只有本人或管理员才能操作
        checkAddressPermission(loginUser, loginUser.getId());

        String oldPassword = req.getOldPassword();
        String newPassword = req.getNewPassword();
        String confirmPassword = req.getConfirmPassword();
        if (!newPassword.equals(confirmPassword)) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "两次输入的密码不一样");
        }

        if (!passwordEncoder.matches(oldPassword, loginUser.getPassword())) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "原密码错误");
        }

        String encoded = passwordEncoder.encode(newPassword);
        boolean updated = userService.updatePasswordById(loginUser.getId(), encoded);
        ThrowUtils.throwIf(!updated, ResultCode.FAILED);

        userService.userLogout(request);

        return JsonResult.success(true);
    }

    /**
     * 获取用户统计数据
     */
    @GetMapping("/analytics/stats")
    public JsonResult<UserStatsVO> getUserStats() {
        UserStatsVO stats = userService.getUserStats();
        return JsonResult.success(stats);
    }

    /**
     * 扣减用户消费金额
     */
    @GetMapping("/api/user/deductAccountBalance/{UserId}/{totalPay}")
    public JsonResult<Boolean> deductAccountBalance(
            @PathVariable("UserId") Long UserId,
            @PathVariable("totalPay") BigDecimal totalPay) {
        
        if (UserId == null || totalPay == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "参数不能为空");
        }
        
        if (totalPay.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "扣减金额必须大于0");
        }
        
        boolean result = userService.deductAccountBalance(UserId, totalPay);
        if (result) {
            return JsonResult.success(true);
        } else {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "扣减用户消费金额失败");
        }
    }

    /**
     * 增加用户消费金额
     */
    @GetMapping("/api/user/addAccountBalance/{UserId}/{totalPay}")
    public JsonResult<Boolean> addAccountBalance(
            @PathVariable("UserId") Long UserId,
            @PathVariable("totalPay") BigDecimal totalPay) {
        
        if (UserId == null || totalPay == null) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "参数不能为空");
        }
        
        if (totalPay.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException(ResultCode.PARAMS_ERROR, "增加金额必须大于0");
        }
        
        boolean result = userService.addAccountBalance(UserId, totalPay);
        if (result) {
            return JsonResult.success(true);
        } else {
            throw new BusinessException(ResultCode.SYSTEM_ERROR, "增加用户消费金额失败");
        }
    }

}
